﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿using jiuyuan.数据.共享类;
using jiuyuan.数据.基础数据类;
using jiuyuan.服务;
using Microsoft.Extensions.Logging;

namespace jiuyuan.管理器;

// 效果参数模板
public class 效果参数模板
{
    public string 效果类型 { get; set; } = "";
    public List<效果参数定义> 参数定义 { get; set; } = [];
}

public class 效果参数定义
{
    public string 参数名 { get; set; } = "";
    public string 显示名称 { get; set; } = "";
    public string 数据类型 { get; set; } = "int";
    public object 默认값 { get; set; } = 0;
    public object 最小값 { get; set; } = 0;
    public object 最大값 { get; set; } = 100;
    public List<string> 枚举选项 { get; set; } = [];
    public string 描述 { get; set; } = "";
}

// 效果处理器接口
public interface I效果处理器
{
    技能效果 创建效果(效果配置 配置);
    string 获取效果描述(效果配置 配置);
}

// 基础效果处理器
public abstract class 基础效果处理器(ILogger 日志器) : I效果处理器
{
    protected readonly ILogger _日志器 = 日志器;

    public abstract 技能效果 创建效果(效果配置 配置);
    public abstract string 获取效果描述(效果配置 配置);

    protected T 获取参数<T>(效果配置 配置, string 参数名, T 默认값)
    {
        if (配置.参数.TryGetValue(参数名, out var value))
        {
            try
            {
                return (T)Convert.ChangeType(value, typeof(T));
            }
            catch
            {
                return 默认값;
            }
        }
        return 默认값;
    }
}

// 具体效果处理器实现
public class 伤害效果处理器 : 基础效果处理器
{
    public 伤害效果处理器(ILogger<伤害效果处理器> 日志器) : base(日志器) { }

    public override 技能效果 创建效果(效果配置 配置)
    {
        return new 动态伤害效果(配置, _日志器);
    }

    public override string 获取效果描述(效果配置 配置)
    {
        var 伤害값 = 获取参数<int>(配置, "伤害值", 0);
        var 伤害系数 = 获取参数<float>(配置, "伤害系数", 1.0f);
        var 元素类型 = 获取参数<string>(配置, "元素类型", "物理");
        return $"造成{伤害값}点{元素类型}伤害(系数{伤害系数})";
    }
}

public class 治疗效果处理器 : 基础效果处理器
{
    public 治疗效果处理器(ILogger<治疗效果处理器> 日志器) : base(日志器) { }

    public override 技能效果 创建效果(效果配置 配置)
    {
        return new 动态治疗效果(配置, _日志器);
    }

    public override string 获取效果描述(效果配置 配置)
    {
        var 治疗量 = 获取参数<int>(配置, "治疗量", 0);
        var 治疗系数 = 获取参数<float>(配置, "治疗系数", 1.0f);
        var 是否群体 = 获取参数<bool>(配置, "是否群体", false);
        return $"恢复{治疗量}点生命值(系数{治疗系数}){(是否群体 ? "，群体治疗" : "")}";
    }
}

public class 速度减益效果处理器 : 基础效果处理器
{
    public 速度减益效果处理器(ILogger<速度减益效果处理器> 日志器) : base(日志器) { }

    public override 技能效果 创建效果(效果配置 配置)
    {
        return new 动态速度减益效果(配置, _日志器);
    }

    public override string 获取效果描述(效果配置 配置)
    {
        var 速度减少值 = 获取参数<int>(配置, "速度减少值", 0);
        var 减少比例 = 获取参数<float>(配置, "减少比例", 0f);
        var 持续回合 = 获取参数<int>(配置, "持续回合数", 2);
        return $"降低速度{速度减少值}点({减少比例:P0})，持续{持续回合}回合";
    }
}

public class 属性增益效果处理器 : 基础效果处理器
{
    public 属性增益效果处理器(ILogger<属性增益效果处理器> 日志器) : base(日志器) { }

    public override 技能效果 创建效果(效果配置 配置)
    {
        return new 动态属性增益效果(配置, _日志器);
    }

    public override string 获取效果描述(效果配置 配置)
    {
        var 持续回合 = 获取参数<int>(配置, "持续回合数", 3);
        var 攻击增益 = 获取参数<int>(配置, "攻击增益", 0);
        var 防御增益 = 获取参数<int>(配置, "防御增益", 0);
        return $"提升攻击{攻击增益}点，防御{防御增益}点，持续{持续回合}回合";
    }
}

// 动态效果基类
public abstract class 动态技能效果 : 技能效果
{
    protected 效果配置 配置;
    protected readonly ILogger _日志器;

    public 动态技能效果(效果配置 配置, ILogger 日志器)
    {
        this.配置 = 配置;
        this._日志器 = 日志器;
        this.Id = 配置.Id;
        this.效果名称 = 配置.名称;
        this.效果描述 = 配置.描述;
        this.触发时机 = Enum.TryParse<效果触发时机>(配置.触发时机, out var 时机) ? 时机 : 效果触发时机.立即触发;
        this.触发概率 = 配置.触发概率;
        this.持续回合数 = 配置.持续回合数;
        this.参数 = new Dictionary<string, object>(配置.参数);
    }

    public override string 效果类型名称 => "动态技能效果";

    public override string 获取描述()
    {
        return 配置.描述;
    }

    protected T 获取参数<T>(string 参数名, T 默认값)
    {
        if (配置.参数.TryGetValue(参数名, out var value))
        {
            try
            {
                return (T)Convert.ChangeType(value, typeof(T));
            }
            catch
            {
                return 默认값;
            }
        }
        return 默认값;
    }

    // 计算基于属性的动态值
    protected int 计算动态值(战斗单位 施法者, int 基础값, string 属性类型, float 系数 = 1.0f)
    {
        var 属性값 = 属性类型.ToLower() switch
        {
            "物理攻击" => 施法者.当前属性.物理攻击,
            "魔法值" => 施法者.当前属性.魔法值,
            "生命值" => 施法者.当前属性.生命值,
            "火属性攻击" => 施法者.当前属性.火属性攻击,
            "水属性攻击" => 施法者.当前属性.水属性攻击,
            "风属性攻击" => 施法者.当前属性.风属性攻击,
            "土属性攻击" => 施法者.当前属性.土属性攻击,
            "速度" => 施法者.当前属性.速度,
            _ => 0
        };

        return (int)(基础값 + 属性값 * 系数);
    }

    // 计算暴击
    protected (int 最终값, bool 是否暴击) 计算暴击값(int 基础값, float 暴击率, float 暴击倍数)
    {
        var 随机 = new Random();
        var 是否暴击 = 随机.NextDouble() < 暴击率;
        var 最终값 = 是否暴击 ? (int)(基础값 * 暴击倍数) : 基础값;
        return (最终값, 是否暴击);
    }

    public abstract override void 应用效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器);
    public abstract override 技能效果 深拷贝();
}

// 具体动态效果实现
public class 动态伤害效果 : 动态技能效果
{
    public 动态伤害效果(效果配置 配置, ILogger 日志器) : base(配置, 日志器) { }

    public override string 效果类型名称 => "动态伤害效果";

    public override void 应用效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        try
        {
            var 基础伤害 = 获取参数<int>("伤害值", 10);
            var 伤害系数 = 获取参数<float>("伤害系数", 1.0f);
            var 元素类型 = 获取参数<string>("元素类型", "物理");
            var 暴击率 = 获取参数<float>("暴击率", 0.1f);
            var 暴击伤害 = 获取参数<float>("暴击伤害", 1.5f);

            // 计算基于施法者属性的动态伤害
            var 计算伤害 = 计算动态值(施法者, 基础伤害, Get属性类型(元素类型), 伤害系数);
            var 随机 = new Random();

            foreach (var 目标 in 目标列表)
            {
                if (!目标.是否存活) continue;

                // 计算暴击
                var (最终伤害, 是否暴击) = 计算暴击값(计算伤害, 暴击率, 暴击伤害);

                // 实际扣血
                目标.当前生命值 = Math.Max(0, 目标.当前生命值 - 最终伤害);

                _日志器.LogInformation("伤害效果: {施法者} -> {目标}, 伤害: {最终伤害}", 施法者.名称, 目标.名称, 最终伤害);

                // 发布伤害事件
                战斗管理器?.事件总线.发布事件(new 伤害造成事件
                {
                    攻击者 = 施法者,
                    受击者 = 目标,
                    伤害值 = 最终伤害,
                    伤害元素 = Get元素类型(元素类型),
                    是否暴击 = 是否暴击,
                    技能名称 = 来源 is 技能配置 技能 ? 技能.名称 : 效果名称
                });

                // 检查目标是否死亡
                if (目标.当前生命值 <= 0)
                {
                    战斗管理器?.事件总线.发布事件(new 单位死亡事件
                    {
                        死亡单位 = 目标,
                        击杀者 = 施法者
                    });
                }
            }
        }
        catch (Exception ex)
        {
            _日志器.LogError(ex, "应用伤害效果时发生错误");
        }
    }

    private 元素属性类型 Get元素类型(string 元素类型)
    {
        return 元素类型.ToLower() switch
        {
            "火" => 元素属性类型.火,
            "水" => 元素属性类型.水,
            "风" => 元素属性类型.风,
            "土" => 元素属性类型.土,
            _ => 元素属性类型.物理
        };
    }

    private string Get属性类型(string 元素类型)
    {
        return 元素类型.ToLower() switch
        {
            "火" => "火属性攻击",
            "水" => "水属性攻击",
            "风" => "风属性攻击",
            "土" => "土属性攻击",
            _ => "物理攻击"
        };
    }

    public override 技能效果 深拷贝()
    {
        return new 动态伤害效果(配置, _日志器);
    }
}

public class 动态治疗效果(效果配置 配置, ILogger 日志器) : 动态技能效果(配置, 日志器)
{
    public override string 效果类型名称 => "动态治疗效果";

    public override void 应用效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        try
        {
            var 基础治疗 = 获取参数<int>("治疗量", 10);
            var 治疗系数 = 获取参数<float>("治疗系数", 1.0f);

            // 计算基于施法者属性的动态治疗量
            var 计算治疗 = 计算动态值(施法者, 基础治疗, "魔法值", 治疗系数);

            foreach (var 目标 in 目标列表)
            {
                if (!目标.是否存活) continue;

                var 原始生命值 = 目标.当前生命值;
                目标.当前生命值 = Math.Min(目标.当前属性.生命值, 目标.当前生命值 + 计算治疗);
                var 实际治疗 = 目标.当前生命值 - 原始生命值;

                _日志器.LogInformation("治疗效果: {施法者} -> {目标}, 治疗: {实际治疗}", 施法者.名称, 目标.名称, 实际治疗);

                // 发布治疗事件
                战斗管理器?.事件总线.发布事件(new 治疗生效事件
                {
                    施法者 = 施法者,
                    目标 = 目标,
                    治疗量 = 实际治疗,
                    技能名称 = 来源 is 技能配置 技能 ? 技能.名称 : 效果名称
                });
            }
        }
        catch (Exception ex)
        {
            _日志器.LogError(ex, "应用治疗效果时发生错误");
        }
    }

    public override 技能效果 深拷贝()
    {
        return new 动态治疗效果(配置, _日志器);
    }
}

public class 动态速度减益效果 : 动态技能效果
{
    public 动态速度减益效果(效果配置 配置, ILogger 日志器) : base(配置, 日志器) { }

    public override string 效果类型名称 => "动态速度减益效果";

    public override void 应用效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        try
        {
            var 速度减少值 = 获取参数<int>("速度减少值", 5);
            var 减少比例 = 获取参数<float>("减少比例", 0.1f);
            var 持续回合 = 获取参数<int>("持续回合数", 2);

            foreach (var 目标 in 目标列表)
            {
                if (!目标.是否存活) continue;

                // 计算实际减少值（基于施法者属性）
                var 实际减少값 = 速度减少值 + (int)(目标.当前属性.速度 * 减少比例);

                // 创建持续效果
                var 持续效果 = new 持续效果
                {
                    效果名称 = 配置.名称,
                    剩余回合数 = 持续回合,
                    基础效果 = this,
                    施加者 = 施法者,
                    目标 = 目标
                };
                持续效果.参数["速度减少值"] = 实际减少값;

                目标.持续效果列表.Add(持续效果);

                _日志器.LogInformation("速度减益: {施法者} -> {目标}, 减少速度: {减少값}", 施法者.名称, 目标.名称, 实际减少값);

                // 立即应用效果
                目标.重新计算属性();
            }
        }
        catch (Exception ex)
        {
            _日志器.LogError(ex, "应用速度减益效果时发生错误");
        }
    }

    public override 技能效果 深拷贝()
    {
        return new 动态速度减益效果(配置, _日志器);
    }
}

public class 动态属性增益效果 : 动态技能效果
{
    public 动态属性增益效果(效果配置 配置, ILogger 日志器) : base(配置, 日志器) { }

    public override string 效果类型名称 => "动态属性增益效果";

    public override void 应用效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        try
        {
            var 攻击增益 = 获取参数<int>("攻击增益", 5);
            var 防御增益 = 获取参数<int>("防御增益", 5);
            var 持续回合 = 获取参数<int>("持续回合数", 3);

            // 计算基于施法者属性的动态增益
            var 动态攻击增益 = 计算动态值(施法者, 攻击增益, "物理攻击", 0.1f);
            var 动态防御增益 = 计算动态值(施法者, 防御增益, "物理防御", 0.1f);

            foreach (var 目标 in 目标列表)
            {
                if (!目标.是否存活) continue;

                // 创建持续效果
                var 持续效果 = new 持续效果
                {
                    效果名称 = 配置.名称,
                    剩余回合数 = 持续回合,
                    基础效果 = this,
                    施加者 = 施法者,
                    目标 = 目标
                };
                持续效果.参数["攻击增益"] = 动态攻击增益;
                持续效果.参数["防御增益"] = 动态防御增益;

                目标.持续效果列表.Add(持续效果);
                目标.重新计算属性();

                _日志器.LogInformation("属性增益: {施法者} -> {目标}, 攻击+{攻击}, 防御+{防御}",
                    施法者.名称, 目标.名称, 动态攻击增益, 动态防御增益);
            }
        }
        catch (Exception ex)
        {
            _日志器.LogError(ex, "应用属性增益效果时发生错误");
        }
    }

    public override 技能效果 深拷贝()
    {
        return new 动态属性增益效果(配置, _日志器);
    }
}

// 重构后的效果管理器
public class 效果管理器
{
    private readonly 事件总线 _事件总线;
    private readonly ILogger<效果管理器> _日志器;
    private readonly IServiceProvider _serviceProvider;
    
    // 延迟加载配置加载器
    private 配置加载器? _配置加载器;

    // 存储所有效果配置
    private readonly Dictionary<Guid, 效果配置> _效果配置字典 = new();

    // 效果处理器映射
    private readonly Dictionary<string, I效果处理器> _效果处理器字典 = new();

    // 效果参数模板
    private readonly Dictionary<string, 效果参数模板> _参数模板字典 = new();

    public 效果管理器(事件总线 事件总线, ILogger<效果管理器> 日志器, IServiceProvider serviceProvider)
    {
        _事件总线 = 事件总线;
        _日志器 = 日志器;
        _serviceProvider = serviceProvider;

        注册内置效果处理器();
        加载参数模板();
    }
    
    // 延迟获取配置加载器
    private 配置加载器 配置加载器 => _配置加载器 ??= _serviceProvider.GetRequiredService<配置加载器>();

    /// <summary>
    /// 注册内置效果处理器
    /// </summary>
    private void 注册内置效果处理器()
    {
        var loggerFactory = new LoggerFactory();
        _效果处理器字典["伤害"] = new 伤害效果处理器(loggerFactory.CreateLogger<伤害效果处理器>());
        _效果处理器字典["治疗"] = new 治疗效果处理器(loggerFactory.CreateLogger<治疗效果处理器>());
        _效果处理器字典["速度减益"] = new 速度减益效果处理器(loggerFactory.CreateLogger<速度减益效果处理器>());
        _效果处理器字典["属性增益"] = new 属性增益效果处理器(loggerFactory.CreateLogger<属性增益效果处理器>());

        _日志器.LogInformation("已注册效果处理器: {处理器数量} 种", _效果处理器字典.Count);
    }

    /// <summary>
    /// 加载参数模板
    /// </summary>
    private void 加载参数模板()
    {
        // 伤害效果模板
        _参数模板字典["伤害"] = new 效果参数模板
        {
            效果类型 = "伤害",
            参数定义 = new List<效果参数定义>
            {
                new() { 参数名 = "伤害值", 显示名称 = "基础伤害", 数据类型 = "int", 默认값 = 10, 最小값 = 0, 最大값 = 1000, 描述 = "基础伤害值" },
                new() { 参数名 = "伤害系数", 显示名称 = "伤害系数", 数据类型 = "float", 默认값 = 1.0f, 最小값 = 0.1f, 最大값 = 5.0f, 描述 = "基于攻击力的伤害系数" },
                new() { 参数名 = "元素类型", 显示名称 = "元素类型", 数据类型 = "enum", 默认값 = "物理", 枚举选项 = new List<string> { "物理", "火", "水", "风", "土" }, 描述 = "伤害元素类型" },
                new() { 参数名 = "暴击率", 显示名称 = "暴击率", 数据类型 = "float", 默认값 = 0.1f, 最小값 = 0f, 最大값 = 1f, 描述 = "暴击概率" },
                new() { 参数名 = "暴击伤害", 显示名称 = "暴击伤害", 数据类型 = "float", 默认값 = 1.5f, 最小값 = 1f, 最大값 = 3f, 描述 = "暴击伤害倍数" }
            }
        };

        // 治疗效果模板
        _参数模板字典["治疗"] = new 效果参数模板
        {
            效果类型 = "治疗",
            参数定义 = new List<效果参数定义>
            {
                new() { 参数名 = "治疗量", 显示名称 = "基础治疗", 数据类型 = "int", 默认값 = 10, 最小값 = 0, 最大값 = 1000, 描述 = "基础治疗量" },
                new() { 参数名 = "治疗系数", 显示名称 = "治疗系数", 数据类型 = "float", 默认값 = 1.0f, 最小값 = 0.1f, 最大값 = 5.0f, 描述 = "基于法术强度的治疗系数" },
                new() { 参数名 = "是否群体", 显示名称 = "群体治疗", 数据类型 = "bool", 默认값 = false, 描述 = "是否对多个目标生效" }
            }
        };

        // 速度减益模板
        _参数模板字典["速度减益"] = new 效果参数模板
        {
            效果类型 = "速度减益",
            参数定义 = new List<效果参数定义>
            {
                new() { 参数名 = "速度减少值", 显示名称 = "速度减少值", 数据类型 = "int", 默认값 = 5, 最小값 = 0, 最大값 = 50, 描述 = "固定速度减少值" },
                new() { 参数名 = "减少比例", 显示名称 = "减少比例", 数据类型 = "float", 默认값 = 0.1f, 最小값 = 0f, 最大값 = 0.5f, 描述 = "按比例减少速度" },
                new() { 参数名 = "持续回合数", 显示名称 = "持续回合", 数据类型 = "int", 默认값 = 2, 最小값 = 1, 最大값 = 10, 描述 = "效果持续回合数" }
            }
        };

        // 属性增益模板
        _参数模板字典["属性增益"] = new 效果参数模板
        {
            效果类型 = "属性增益",
            参数定义 = new List<效果参数定义>
            {
                new() { 参数名 = "攻击增益", 显示名称 = "攻击增益", 数据类型 = "int", 默认값 = 5, 最小값 = 0, 最大값 = 100, 描述 = "攻击力提升值" },
                new() { 参数名 = "防御增益", 显示名称 = "防御增益", 数据类型 = "int", 默认값 = 5, 最小값 = 0, 最大값 = 100, 描述 = "防御力提升值" },
                new() { 参数名 = "持续回合数", 显示名称 = "持续回合", 数据类型 = "int", 默认값 = 3, 最小값 = 1, 最大값 = 10, 描述 = "效果持续回合数" }
            }
        };
    }

    /// <summary>
    /// 注册效果配置
    /// </summary>
    public void 注册效果配置(效果配置 配置)
    {
        _效果配置字典[配置.Id] = 配置;
        _日志器.LogInformation("注册效果配置: {效果名称}", 配置.名称);
    }

    /// <summary>
    /// 根据效果配置创建效果实例
    /// </summary>
    public 技能效果 创建效果(效果配置 配置)
    {
        if (_效果处理器字典.TryGetValue(配置.效果类型, out var 处理器))
        {
            var 效果 = 处理器.创建效果(配置);
            _日志器.LogDebug("创建效果实例: {效果名称}", 配置.名称);
            return 效果;
        }

        _日志器.LogWarning("未知的效果类型: {效果类型}", 配置.效果类型);
        return null;
    }

    /// <summary>
    /// 根据ID获取效果实例
    /// </summary>
    public 技能效果 获取效果(Guid 效果ID)
    {
        if (_效果配置字典.TryGetValue(效果ID, out var 配置))
        {
            return 创建效果(配置);
        }
        return null;
    }

    /// <summary>
    /// 获取效果配置
    /// </summary>
    public 效果配置 获取效果配置(Guid 效果ID)
    {
        return _效果配置字典.TryGetValue(效果ID, out var 配置) ? 配置 : null;
    }

    /// <summary>
    /// 获取所有效果配置
    /// </summary>
    public List<效果配置> 获取所有效果配置()
    {
        return _效果配置字典.Values.ToList();
    }

    /// <summary>
    /// 获取效果参数模板
    /// </summary>
    public 效果参数模板 获取参数模板(string 效果类型)
    {
        return _参数模板字典.TryGetValue(效果类型, out var 模板) ? 模板 : null;
    }

    /// <summary>
    /// 获取所有效果类型
    /// </summary>
    public List<string> 获取所有效果类型()
    {
        return _效果处理器字典.Keys.ToList();
    }

    /// <summary>
    /// 保存效果配置
    /// </summary>
    public async Task 保存效果配置(效果配置 配置)
    {
        配置.更新时间 = DateTime.Now;
        _效果配置字典[配置.Id] = 配置;

        await _配置加载器.保存效果配置(配置);
        _日志器.LogInformation("保存效果配置: {效果名称}", 配置.名称);
    }

    /// <summary>
    /// 删除效果配置
    /// </summary>
    public async Task 删除效果配置(Guid 效果ID)
    {
        if (_效果配置字典.Remove(效果ID))
        {
            await _配置加载器.删除效果配置(效果ID);
            _日志器.LogInformation("删除效果配置: {效果ID}", 效果ID);
        }
    }

    /// <summary>
    /// 获取效果描述
    /// </summary>
    public string 获取效果描述(效果配置 配置)
    {
        if (_效果处理器字典.TryGetValue(配置.效果类型, out var 处理器))
        {
            return 处理器.获取效果描述(配置);
        }
        return "未知效果";
    }
    
    /// <summary>
    /// 从数据库加载所有效果配置
    /// </summary>
    public async Task<List<效果配置>> 获取所有效果配置From数据库()
    {
        return await _配置加载器.获取所有效果配置();
    }
    
    /// <summary>
    /// 处理回合结束效果
    /// </summary>
    public async Task 处理回合结束效果(战斗单位 单位, 战斗管理器 战斗管理器)
    {
        // 处理回合结束效果的逻辑
        // 这里可以添加具体实现
        await Task.CompletedTask;
    }
}